package de.koller.planet2D.aRenderer;

import de.koller.aframe.util.thread.ILoopHandler;
import de.koller.aframe.util.thread.ThreadRootHandle;
import de.koller.oceanFramework.gl.util.ImagePreview;
import de.koller.planet2D.container.FrameClip;
import de.koller.planet2D.frame.rendering.Renderizer;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class Renderer implements ILoopHandler {

	private static int nextID = 1;
	
	protected final Renderizer renderizer;
	private final String name;
	public final int frameW, frameH;
	private final int id;
	
	private final ThreadRootHandle thread;

	protected BufferedImage frame;
	protected Graphics2D frameGraphics;
	private RenderStep primitivRenderer = new PrimitivRenderStep( this );
	
	public Renderer( Renderizer renderizer, String name, int frameW, int frameH ) {
		this.renderizer = renderizer;
		this.name = name;
		this.frameW = frameW;
		this.frameH = frameH;
		
		id = nextID;
		nextID++;
		
		thread = new ThreadRootHandle( "Renderer_" + id );
		thread.getThread().setDaemon( true );
		thread.setLoopHandler( this );
		thread.start();
	}

	@Override
	public void loopHandle() {
	
		renderizer.getProgress().setString( "initialisieren" );
		
		frame = new BufferedImage( frameW, frameH, BufferedImage.TYPE_INT_ARGB );
		for( int x = 0; x < frame.getWidth(); x++ )
			for( int y = 0; y < frame.getHeight(); y++ )
				frame.setRGB( x, y, 0xff000000 );
		frameGraphics = frame.createGraphics();
		
		frameGraphics.setRenderingHint( RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY );
		frameGraphics.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
		frameGraphics.setRenderingHint( RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY );
		frameGraphics.setRenderingHint( RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON );
		frameGraphics.setRenderingHint( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC );
		frameGraphics.setRenderingHint( RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY );
		
		transformToCamera();
		
		primitivRenderer.initProgressBar( 1, renderizer.getProgress() );
		primitivRenderer.renderStep( 1, renderizer.getProgress() );
		
		renderizer.getProgress().setString( "fertig" );
		renderizer.readyRendered();
		thread.stop();
		
		try {
			ImageIO.write( frame, "png", new File( "./output/" + name + "_0.png" ) );
		} catch( IOException ex ) { System.err.println( ex ); }
		ImagePreview.showImage( frame, 1280, 720 );
	}

	private void transformToCamera() {
		FrameClip fc = renderizer.proot.renderContainer.frameClip;
		
		frameGraphics.scale( (double)frameW / fc.size.getX(), (double)frameH / fc.size.getY() );
		frameGraphics.translate( -fc.position.getX(), -fc.position.getY() );
		frameGraphics.translate( fc.size.getX() / 2., fc.size.getY() / 2. );
		frameGraphics.rotate( Math.toRadians( -fc.rotation ), fc.position.getX(), fc.position.getY() );
	}
	
}
